package org.igetwell.common.utils;
  
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;

/**
 * HttpClient工具类
 */
@Slf4j
public class HttpClientUtils {

    private RequestConfig requestConfig = RequestConfig.custom()
        .setSocketTimeout(15000)  
        .setConnectTimeout(15000)  
        .setConnectionRequestTimeout(15000)  
        .build();  
      
    private static HttpClientUtils instance = null;
    private HttpClientUtils(){}
    public static HttpClientUtils getInstance(){
        if (instance == null) {    
            instance = new HttpClientUtils();
        }    
        return instance;  
    }    
        
    /**  
     * 发送 post请求  
     * @param httpUrl 地址  
     */    
    public String sendHttpPost(String httpUrl,String charset) {    
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost

        return sendHttpPost(httpPost,charset);
    }    
        
    /**  
     * 发送 post请求  
     * @param httpUrl 地址  
     * @param params 参数(格式:key1=value1&key2=value2)  
     */    
    public String sendHttpPost(String httpUrl, String params,String charset) {    
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost      
        try {    
            //设置参数    
            StringEntity stringEntity = new StringEntity(params, "UTF-8");    
            stringEntity.setContentType("application/x-www-form-urlencoded");    
            httpPost.setEntity(stringEntity);    
        } catch (Exception e) {    
            e.printStackTrace();    
        }    
        return sendHttpPost(httpPost,charset);    
    }    
        
    /**  
     * 发送 post请求  
     * @param httpUrl 地址  
     * @param maps 参数  
     */    
    public String sendHttpPost(String httpUrl, Map<String, String> maps, String charset) {
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost      
        // 创建参数队列      
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();    
        for (String key : maps.keySet()) {    
            nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));    
        }    
        try {    
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));    
        } catch (Exception e) {
            log.error("sendHttpPost请求失败：", e);
        }    
        return sendHttpPost(httpPost,charset);    
    }

    /**
     * 发送 post请求
     * @param httpUrl 地址
     * @param headers 请求头
     * @param params 参数
     * @param charset
     * @return
     */
    public String sendHttpPost(String httpUrl, Map<String, String> headers, Map<String, Object> params, String charset){
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
        if (!CollectionUtils.isEmpty(headers)){
            for(Map.Entry<String, String> entry : headers.entrySet()){
                httpPost.setHeader(entry.getKey(), entry.getValue());
            }
        }

        if (params.isEmpty()){
            log.error("请求参数不能为空!");
            return null;
        }
        try {
            String json = JSON.toJSONString(params);
            StringEntity entity = new StringEntity(json, "UTF-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);

        } catch (Exception e) {
            log.error("sendHttpPost请求失败：", e);
        }
        return sendHttpPost(httpPost, charset);
    }

    /**
     * 发送 post请求（带文件）
     * @param httpUrl 地址
     * @param maps 参数
     * @param fileMap 附件
     */
    public String multipartFile(String httpUrl, Map<String, String> maps, Map<String, File> fileMap, String charset) {
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        for(Map.Entry<String, File> entry : fileMap.entrySet()){
            FileBody fileBody = new FileBody(entry.getValue());
            // add the file params
            multipartEntityBuilder.addPart(entry.getKey(), fileBody);
        }
        // 设置上传的其他参数
        setUploadParams(multipartEntityBuilder, maps);
        HttpEntity entity = multipartEntityBuilder.build();
        httpPost.setEntity(entity);
        return sendHttpPost(httpPost,charset);
    }

    /**
     * 发送 post请求（带文件）
     * @param httpUrl 地址
     * @param maps 参数
     * @param fileMap 附件
     */
    public String multipartFile(String httpUrl, Map<String, String> headers, Map<String, String> maps, Map<String, File> fileMap, String charset) {
        HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
        for(Map.Entry<String, String> entry : headers.entrySet()){
            httpPost.setHeader(entry.getKey(), entry.getValue());
        }
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        for(Map.Entry<String, File> entry : fileMap.entrySet()){
            FileBody fileBody = new FileBody(entry.getValue());
            // add the file params
            multipartEntityBuilder.addPart(entry.getKey(), fileBody);
        }

        // 设置上传的其他参数
        setUploadParams(multipartEntityBuilder, maps);
        HttpEntity entity = multipartEntityBuilder.build();
        httpPost.setEntity(entity);

        return sendHttpPost(httpPost,charset);
    }

    /**
     * 设置上传文件时所附带的其他参数
     *
     * @param multipartEntityBuilder
     * @param params
     */
    private void setUploadParams(MultipartEntityBuilder multipartEntityBuilder,
                                 Map<String, String> params) {
        if (params != null && params.size() > 0) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                multipartEntityBuilder
                        .addPart(key, new StringBody(params.get(key),
                                ContentType.TEXT_PLAIN));
            }
        }
    }

    /**  
     * 发送Post请求  
     * @param httpPost  
     * @return  
     */    
    private String sendHttpPost(HttpPost httpPost,String charset) {    
        CloseableHttpClient httpClient = null;    
        CloseableHttpResponse response = null;    
        HttpEntity entity = null;    
        String responseContent = null;    
        try {    
            // 创建默认的httpClient实例.    
            httpClient = HttpClients.createDefault();    
            httpPost.setConfig(requestConfig);    
            // 执行请求    
            response = httpClient.execute(httpPost);    
            entity = response.getEntity();    
            responseContent = EntityUtils.toString(entity,charset);    
        } catch (Exception e) {    
            e.printStackTrace();    
        } finally {    
            try {    
                // 关闭连接,释放资源    
                if (response != null) {    
                    response.close();    
                }    
                if (httpClient != null) {    
                    httpClient.close();    
                }    
            } catch (IOException e) {    
                e.printStackTrace();    
            }    
        }    
        return responseContent;    
    }    
    
    /**  
     * 发送 get请求  
     * @param httpUrl  
     */    
    public String sendHttpGet(String httpUrl) {    
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求    
        return sendHttpGet(httpGet);    
    }    
        
    /**  
     * 发送 get请求Https  
     * @param httpUrl  
     */    
    public String sendHttpsGet(String httpUrl) {    
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求    
        return sendHttpsGet(httpGet);    
    }

    /**
     * 发送 get请求Https
     * @param httpUrl
     */
    public String sendHttpsGet(String httpUrl, Map<String, Object> params) throws IOException {
        if (params != null && params.size() > 0) {
            Set<String> keys = params.keySet();
            // 创建参数队列
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            for (String key : params.keySet()) {
                nameValuePairs.add(new BasicNameValuePair(key, params.get(key).toString()));
            }
            httpUrl +="?"+EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairs),"UTF-8");

        }
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
        return sendHttpsGet(httpGet);
    }



    /**  
     * 发送Get请求  
     * @param httpGet
     * @return  
     */    
    private String sendHttpGet(HttpGet httpGet) {    
        CloseableHttpClient httpClient = null;    
        CloseableHttpResponse response = null;    
        HttpEntity entity = null;    
        String responseContent = null;    
        try {    
            // 创建默认的httpClient实例.    
            httpClient = HttpClients.createDefault();    
            httpGet.setConfig(requestConfig);    
            // 执行请求    
            response = httpClient.execute(httpGet);    
            entity = response.getEntity();    
            responseContent = EntityUtils.toString(entity, "UTF-8");    
        } catch (Exception e) {    
            e.printStackTrace();    
        } finally {    
            try {    
                // 关闭连接,释放资源    
                if (response != null) {    
                    response.close();    
                }    
                if (httpClient != null) {    
                    httpClient.close();    
                }    
            } catch (IOException e) {    
                e.printStackTrace();    
            }    
        }    
        return responseContent;    
    }
        
    /**  
     * 发送Get请求Https  
     * @param httpGet
     * @return  
     */    
    private String sendHttpsGet(HttpGet httpGet) {    
        CloseableHttpClient httpClient = null;    
        CloseableHttpResponse response = null;    
        HttpEntity entity = null;    
        String responseContent = null;    
        try {    
            // 创建默认的httpClient实例.    
            PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpGet.getURI().toString()));    
            DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);    
            httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build();    
            httpGet.setConfig(requestConfig);    
            // 执行请求    
            response = httpClient.execute(httpGet);    
            entity = response.getEntity();    
            responseContent = EntityUtils.toString(entity, "UTF-8");    
        } catch (Exception e) {    
            e.printStackTrace();    
        } finally {    
            try {    
                // 关闭连接,释放资源    
                if (response != null) {    
                    response.close();    
                }    
                if (httpClient != null) {    
                    httpClient.close();    
                }    
            } catch (IOException e) {    
                e.printStackTrace();    
            }    
        }    
        return responseContent;    
    }  
}